home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / src / mouse.c < prev    next >
Text File  |  1993-12-06  |  16KB  |  658 lines

  1. /**
  2.  ** MOUSE.C
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "grx.h"
  25. #include "mousex.h"
  26. #include "libgrx.h"
  27. #include "interrup.h"
  28. #include "clipping.h"
  29.  
  30. #include "../events/eventque.h"
  31. #include <string.h>
  32. #include <stdarg.h>
  33.  
  34. #ifdef __TURBOC__
  35. # include <time.h>
  36. # include <conio.h>
  37. #endif
  38.  
  39. #ifdef __GNUC__
  40.   extern  long        rawclock();
  41. # define  clock()   rawclock()
  42. #endif
  43.  
  44. /*
  45.  * mouse status flags
  46.  */
  47. #define UNKNOWN        0
  48. #define MISSING        1
  49. #define PRESENT        2
  50. #define INITTED        3
  51. #define QUEUED        4
  52.  
  53. #define DRAW_STACK  1024
  54. #define QUEUE_SIZE  100
  55.  
  56. #define CHECK_CONTEXT(cxt)  ((cxt)->gc_baseaddr == SCREEN->gc_baseaddr)
  57.  
  58. extern GrCursor *_GrMouseCursor;    /* current mouse cursor */
  59.  
  60. static EventQueue *queue,qbuf;
  61. static int mouse_status = UNKNOWN;
  62. static int own_cursor    = FALSE;
  63. static int use_queue    = FALSE;
  64. static int kb_enable    = TRUE;
  65. static int ms_enable    = TRUE;
  66. static int ms_curmode    = M_CUR_NORMAL;
  67. static int ms_xanchor,ms_yanchor;
  68. static int ms_dx2,ms_dy2;
  69. static int ms_curcolor;
  70. static int ms_buttons;
  71. static int ms_xpos;
  72. static int ms_ypos;
  73.  
  74. #define ms_dx1  ms_xanchor
  75. #define ms_dy1  ms_yanchor
  76.  
  77. static void (*getevent)(int flags,MouseEvent *event);
  78.  
  79. static char ptr12x16bits[] = {
  80.     0,1,0,0,0,0,0,0,0,0,0,0,
  81.     1,2,1,0,0,0,0,0,0,0,0,0,
  82.     1,2,2,1,0,0,0,0,0,0,0,0,
  83.     1,2,2,2,1,0,0,0,0,0,0,0,
  84.     1,2,2,2,2,1,0,0,0,0,0,0,
  85.     1,2,2,2,2,2,1,0,0,0,0,0,
  86.     1,2,2,2,2,2,2,1,0,0,0,0,
  87.     1,2,2,2,2,2,2,2,1,0,0,0,
  88.     1,2,2,2,2,2,2,2,2,1,0,0,
  89.     1,2,2,2,2,2,2,2,2,2,1,0,
  90.     1,2,2,2,2,2,2,2,2,2,2,1,
  91.     1,2,2,2,2,1,1,1,1,1,1,0,
  92.     1,2,2,2,1,0,0,0,0,0,0,0,
  93.     1,2,2,1,0,0,0,0,0,0,0,0,
  94.     1,2,1,0,0,0,0,0,0,0,0,0,
  95.     0,1,0,0,0,0,0,0,0,0,0,0,
  96. };
  97.  
  98. static int check_mouse(void)
  99. {
  100.     if(mouse_status < INITTED) {
  101.         if(mouse_status != MISSING) MouseInit();
  102.         if(mouse_status <  INITTED) return(FALSE);
  103.     }
  104.     return(TRUE);
  105. }
  106.  
  107. static void draw_special(void)
  108. {
  109.     int x = _GrMouseCursor->cr_xcord;
  110.     int y = _GrMouseCursor->cr_ycord;
  111.     int msflag = _GrMouseCheck;
  112.     GrContext csave;
  113.  
  114.     csave = *CURC;
  115.     *CURC = *SCREEN;
  116.     _GrMouseCheck = FALSE;
  117.     switch(ms_curmode) {
  118.       case M_CUR_RUBBER:
  119.         GrBox(x,y,ms_xanchor,ms_yanchor,ms_curcolor);
  120.         break;
  121.       case M_CUR_LINE:
  122.         GrLine(x,y,ms_xanchor,ms_yanchor,ms_curcolor);
  123.         break;
  124.       case M_CUR_BOX:
  125.         GrBox(x+ms_dx1,y+ms_dy1,x+ms_dx2,y+ms_dy2,ms_curcolor);
  126.         break;
  127.     }
  128.     *CURC = csave;
  129.     _GrMouseCheck = msflag;
  130. }
  131.  
  132. static void draw_mouse(void)
  133. {
  134.     if(_GrMouseCursor->cr_displayed) return;
  135.     GrMoveCursor(_GrMouseCursor,queue->evq_xpos,queue->evq_ypos);
  136.     GrDisplayCursor(_GrMouseCursor);
  137.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  138. }
  139.  
  140. static void erase_mouse(void)
  141. {
  142.     if(!_GrMouseCursor->cr_displayed) return;
  143.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  144.     GrEraseCursor(_GrMouseCursor);
  145. }
  146.  
  147. static void move_mouse(void)
  148. {
  149. #ifdef CRASH_AT_0_0
  150.     if((queue->evq_xpos == 0) && (queue->evq_ypos == 0)) {
  151.         char tmp[20];
  152.         char *ptr = (char *)NULL;
  153.         int  crashval = ++(*ptr);
  154.         sprintf(tmp,"%d",crashval);
  155.     }
  156. #endif
  157.     if(!_GrMouseCursor->cr_displayed) {
  158.         GrMoveCursor(_GrMouseCursor,queue->evq_xpos,queue->evq_ypos);
  159.         return;
  160.     }
  161.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  162.     GrMoveCursor(_GrMouseCursor,queue->evq_xpos,queue->evq_ypos);
  163.     if(ms_curmode != M_CUR_NORMAL) draw_special();
  164. }
  165.  
  166. static void get_polled_event(int flags,MouseEvent *e)
  167. {
  168.     REGISTERS regs;
  169.     int moved;
  170.     int diff;
  171.  
  172.     for( ; ; ) {
  173.         if((flags & M_KEYPRESS) && kbhit()) {
  174.         e->flags  = M_KEYPRESS;
  175.         e->x      = queue->evq_xpos;
  176.         e->y      = queue->evq_ypos;
  177.         e->key      = getxkey();
  178.         e->kbstat = getkbstat();
  179.         e->time      = clock();
  180.         return;
  181.         }
  182.         moved = 0;
  183.         regs.r_ax = 11;
  184.         int33(®s);
  185.         if((diff = (short)regs.r_cx) != 0) {
  186.         ms_xpos += diff;
  187.         if((diff = ms_xpos / queue->evq_xspeed) != 0) {
  188.             ms_xpos %= queue->evq_xspeed;
  189.             if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  190.             diff += queue->evq_xpos;
  191.             if(diff <= queue->evq_xmin) diff = queue->evq_xmin;
  192.             if(diff >= queue->evq_xmax) diff = queue->evq_xmax;
  193.             if(diff != queue->evq_xpos) {
  194.             queue->evq_xpos  = diff;
  195.             queue->evq_moved = 1;
  196.             moved = M_MOTION;
  197.             }
  198.         }
  199.         }
  200.         if((diff = (short)regs.r_dx) != 0) {
  201.         ms_ypos += diff;
  202.         if((diff = ms_ypos / queue->evq_yspeed) != 0) {
  203.             ms_ypos %= queue->evq_yspeed;
  204.             if(IABS(diff) >= queue->evq_thresh) diff *= queue->evq_accel;
  205.             diff += queue->evq_ypos;
  206.             if(diff <= queue->evq_ymin) diff = queue->evq_ymin;
  207.             if(diff >= queue->evq_ymax) diff = queue->evq_ymax;
  208.             if(diff != queue->evq_ypos) {
  209.             queue->evq_ypos  = diff;
  210.             queue->evq_moved = 1;
  211.             moved = M_MOTION;
  212.             }
  213.         }
  214.         }
  215.         if(moved && queue->evq_drawmouse) move_mouse();
  216.         regs.r_ax = 3;
  217.         int33(®s);
  218.         if(flags & M_BUTTON_DOWN) {
  219.         diff = (regs.r_bx & ~ms_buttons);
  220.         if(diff & M_LEFT)   moved |= M_LEFT_DOWN;
  221.         if(diff & M_MIDDLE) moved |= M_MIDDLE_DOWN;
  222.         if(diff & M_RIGHT)  moved |= M_RIGHT_DOWN;
  223.         }
  224.         if(flags & M_BUTTON_UP) {
  225.         diff = (~regs.r_bx & ms_buttons);
  226.         if(diff & M_LEFT)   moved |= M_LEFT_UP;
  227.         if(diff & M_MIDDLE) moved |= M_MIDDLE_UP;
  228.         if(diff & M_RIGHT)  moved |= M_RIGHT_UP;
  229.         }
  230.         ms_buttons = regs.r_bx & (M_LEFT | M_MIDDLE | M_RIGHT);
  231.         if(flags & (moved | M_POLL)) {
  232.         e->flags   = moved & flags;
  233.         e->x       = queue->evq_xpos;
  234.         e->y       = queue->evq_ypos;
  235.         e->buttons = ms_buttons;
  236.         e->kbstat  = getkbstat();
  237.         e->time       = clock();
  238.         return;
  239.         }
  240.     }
  241. }
  242.  
  243. static void get_queued_event(int flags,MouseEvent *e)
  244. {
  245.     EventRecord evr;
  246.     int moved = 0;
  247.  
  248.     for( ; ; ) {
  249.         if(queue->evq_moved) {
  250.         moved = M_MOTION;
  251.         queue->evq_moved = 0;
  252.         }
  253.         if(EventQueueNextEvent(queue,&evr)) {
  254.         switch(evr.evt_type) {
  255.           case EVENT_KEYBD:
  256.             if(flags & M_KEYPRESS) {
  257.             e->flags   = M_KEYPRESS;
  258.             e->x       = queue->evq_xpos;
  259.             e->y       = queue->evq_ypos;
  260.             e->key       = evr.evt_keycode;
  261.             e->kbstat  = evr.evt_kbstat;
  262.             e->time       = evr.evt_time;
  263.             return;
  264.             }
  265.             break;
  266.           case EVENT_MOUSE:
  267.             ms_buttons = evr.evt_button;
  268.             if(flags & evr.evt_mask) {
  269.             e->flags   = flags & (evr.evt_mask | moved);
  270.             e->x       = evr.evt_xpos;
  271.             e->y       = evr.evt_ypos;
  272.             e->buttons = evr.evt_button;
  273.             e->kbstat  = evr.evt_kbstat;
  274.             e->time       = evr.evt_time;
  275.             return;
  276.             }
  277.             break;
  278.         }
  279.         continue;
  280.         }
  281.         if(flags & (moved | M_POLL)) {
  282.         e->flags   = flags & moved;
  283.         e->x       = queue->evq_xpos;
  284.         e->y       = queue->evq_ypos;
  285.         e->buttons = ms_buttons;
  286.         e->kbstat  = getkbstat();
  287.         e->time       = clock();
  288.         return;
  289.         }
  290.     }
  291. }
  292.  
  293. void MouseEventMode(int use_interrupts)
  294. {
  295.     use_queue = use_interrupts;
  296. }
  297.  
  298. int MouseDetect(void)
  299. {
  300.     REGISTERS regs;
  301.  
  302.     if(mouse_status == UNKNOWN) {
  303.         regs.r_ax = 0;
  304.         int33(®s);
  305.         mouse_status = (regs.r_ax == 0) ? MISSING : PRESENT;
  306.     }
  307.     return((mouse_status == MISSING) ? FALSE : TRUE);
  308. }
  309.  
  310. void MouseUnInit(void)
  311. {
  312.     REGISTERS regs;
  313.  
  314.     if(mouse_status >= INITTED) {
  315.         if(mouse_status == QUEUED) {
  316.         EventQueueDeInit();
  317.         queue = NULL;
  318.         }
  319.         else {
  320.         regs.r_ax = 0;
  321.         int33(®s);
  322.         }
  323.         if(_GrMouseDrawn) erase_mouse();
  324.         mouse_status = PRESENT;
  325.     }
  326. }
  327.  
  328. void MouseInit(void)
  329. {
  330.     REGISTERS regs;
  331.  
  332.     if(mouse_status != PRESENT) {
  333.         MouseDetect();
  334.         MouseUnInit();
  335.         if(mouse_status != PRESENT) return;
  336.     }
  337.     if(use_queue) {
  338.         queue = EventQueueInit(QUEUE_SIZE,DRAW_STACK,move_mouse);
  339.         if(queue != NULL) {
  340.         mouse_status = QUEUED;
  341.         getevent = get_queued_event;
  342.         queue->evq_drawmouse = FALSE;
  343.         }
  344.     }
  345.     if(mouse_status < INITTED) {
  346.         queue = &qbuf;
  347.         regs.r_ax = 0;
  348.         int33(®s);
  349.         regs.r_ax = 3;
  350.         int33(®s);
  351.         ms_buttons = regs.r_bx & (M_LEFT | M_MIDDLE | M_RIGHT);
  352.         regs.r_ax = 11;
  353.         int33(®s);
  354.         ms_xpos = 0;
  355.         ms_ypos = 0;
  356.         getevent = get_polled_event;
  357.         mouse_status = INITTED;
  358.     }
  359.     if(_GrMouseCursor == NULL) MouseSetColors(GrWhite(),GrBlack());
  360.     _GrMouseBlock    = MouseBlock;
  361.     _GrMouseUnBlock = MouseUnBlock;
  362.     _GrMouseUnInit  = MouseUnInit;
  363.     _GrMouseDrawn    = FALSE;
  364.     _GrMouseCheck    = FALSE;
  365.     MouseEventEnable(kb_enable,ms_enable);
  366.     MouseSetLimits(0,0,(_GrScreenX - 1),(_GrScreenY - 1));
  367.     MouseWarp((_GrScreenX >> 1),(_GrScreenY >> 1));
  368.     MouseSetSpeed(1);
  369.     MouseSetAccel(1000,1);
  370. }
  371.  
  372. void MouseSetSpeed(int speed)
  373. {
  374.     if(!check_mouse()) return;
  375.     queue->evq_xspeed = speed;
  376.     queue->evq_yspeed = speed;
  377. }
  378.  
  379. void MouseSetAccel(int thresh,int accel)
  380. {
  381.     if(!check_mouse()) return;
  382.     queue->evq_thresh = thresh;
  383.     queue->evq_accel  = accel;
  384. }
  385.  
  386. void MouseSetLimits(int x1,int y1,int x2,int y2)
  387. {
  388.     if(!check_mouse()) return;
  389.     CLIPBOXTOCONTEXT(SCREEN,x1,y1,x2,y2);
  390.     queue->evq_xmin = x1;
  391.     queue->evq_ymin = y1;
  392.     queue->evq_xmax = x2;
  393.     queue->evq_ymax = y2;
  394.     MouseWarp(queue->evq_xpos,queue->evq_ypos);
  395. }
  396.  
  397. void MouseGetLimits(int *x1,int *y1,int *x2,int *y2)
  398. {
  399.     if(!check_mouse()) return;
  400.     *x1 = queue->evq_xmin;
  401.     *y1 = queue->evq_ymin;
  402.     *x2 = queue->evq_xmax;
  403.     *y2 = queue->evq_ymax;
  404. }
  405.  
  406. void MouseWarp(int x,int y)
  407. {
  408.     char msdraw;
  409.  
  410.     if(!check_mouse()) return;
  411.     msdraw = queue->evq_drawmouse;
  412.     queue->evq_drawmouse = FALSE;
  413.     if(x < queue->evq_xmin) x = queue->evq_xmin;
  414.     if(y < queue->evq_ymin) y = queue->evq_ymin;
  415.     if(x > queue->evq_xmax) x = queue->evq_xmax;
  416.     if(y > queue->evq_ymax) y = queue->evq_ymax;
  417.     queue->evq_xpos = x;
  418.     queue->evq_ypos = y;
  419.     if(_GrMouseDrawn) move_mouse();
  420.     queue->evq_drawmouse = msdraw;
  421. }
  422.  
  423. void MouseSetCursor(GrCursor *cursor)
  424. {
  425.     GrCursor *old = _GrMouseCursor;
  426.     char msdraw = 0;
  427.  
  428.     if(cursor != NULL) {
  429.         if(mouse_status >= INITTED) {
  430.         msdraw = queue->evq_drawmouse;
  431.         queue->evq_drawmouse = FALSE;
  432.         if(_GrMouseDrawn) erase_mouse();
  433.         }
  434.         _GrMouseCursor = cursor;
  435.         if(own_cursor) GrDestroyCursor(old);
  436.         own_cursor = FALSE;
  437.         if(mouse_status >= INITTED) {
  438.         if(_GrMouseDrawn) draw_mouse();
  439.         queue->evq_drawmouse = msdraw;
  440.         }
  441.     }
  442. }
  443.  
  444. void MouseSetColors(int fg,int bg)
  445. {
  446.     GrCursor *new;
  447.     int cols[3];
  448.  
  449.     cols[0] = 2;
  450.     cols[1] = bg;
  451.     cols[2] = fg;
  452.     new = GrBuildCursor(ptr12x16bits,12,16,1,1,cols);
  453.     if(new != NULL) {
  454.         MouseSetCursor(new);
  455.         own_cursor = TRUE;
  456.     }
  457. }
  458.  
  459. void MouseSetCursorMode(int mode,...)
  460. {
  461.     va_list ap;
  462.     char msdraw = 0;
  463.  
  464.     if(mouse_status >= INITTED) {
  465.         msdraw = queue->evq_drawmouse;
  466.         queue->evq_drawmouse = FALSE;
  467.         if(_GrMouseDrawn && (ms_curmode != M_CUR_NORMAL)) draw_special();
  468.     }
  469.     va_start(ap,mode);
  470.     switch(mode) {
  471.       case M_CUR_RUBBER:
  472.         ms_curmode  = M_CUR_RUBBER;
  473.         ms_xanchor  = va_arg(ap,int);
  474.         ms_yanchor  = va_arg(ap,int);
  475.         ms_curcolor = (va_arg(ap,int) & C_COLOR) | GrXOR;
  476.         break;
  477.       case M_CUR_LINE:
  478.         ms_curmode  = M_CUR_LINE;
  479.         ms_xanchor  = va_arg(ap,int);
  480.         ms_yanchor  = va_arg(ap,int);
  481.         ms_curcolor = (va_arg(ap,int) & C_COLOR) | GrXOR;
  482.         break;
  483.       case M_CUR_BOX:
  484.         ms_curmode  = M_CUR_BOX;
  485.         ms_dx1    = va_arg(ap,int);
  486.         ms_dy1    = va_arg(ap,int);
  487.         ms_dx2    = va_arg(ap,int);
  488.         ms_dy2    = va_arg(ap,int);
  489.         ms_curcolor = (va_arg(ap,int) & C_COLOR) | GrXOR;
  490.         break;
  491.       default:
  492.         ms_curmode  = M_CUR_NORMAL;
  493.         break;
  494.     }
  495.     va_end(ap);
  496.     if(mouse_status >= INITTED) {
  497.         if(_GrMouseDrawn && (ms_curmode != M_CUR_NORMAL)) draw_special();
  498.         queue->evq_drawmouse = msdraw;
  499.     }
  500. }
  501.  
  502. GrCursor *MouseGetCursor(void)
  503. {
  504.     return(_GrMouseCursor);
  505. }
  506.  
  507. int MouseCursorIsDisplayed(void)
  508. {
  509.     return(_GrMouseDrawn);
  510. }
  511.  
  512. void MouseDisplayCursor(void)
  513. {
  514.     if((mouse_status < INITTED) || _GrMouseDrawn) return;
  515.     draw_mouse();
  516.     _GrMouseDrawn = TRUE;
  517.     _GrMouseCheck = CHECK_CONTEXT(CURC) ? TRUE : FALSE;
  518.     queue->evq_drawmouse = TRUE;
  519. }
  520.  
  521. void MouseEraseCursor(void)
  522. {
  523.     if((mouse_status < INITTED) || !_GrMouseDrawn) return;
  524.     queue->evq_drawmouse = FALSE;
  525.     _GrMouseDrawn = FALSE;
  526.     _GrMouseCheck = FALSE;
  527.     erase_mouse();
  528. }
  529.  
  530. #define BLK_MOTION  1        /* "MouseBlock" froze the mouse */
  531. #define BLK_DISPLAY 2        /* "MouseBlock" erased the mouse */
  532. #define BLK_CHECK   4        /* "MouseBlock" cleared check flag */
  533.  
  534. int MouseBlock(GrContext *c,int x1,int y1,int x2,int y2)
  535. {
  536.     int mx1,my1,mx2,my2;
  537.     int retval;
  538.  
  539.     if(mouse_status < INITTED) return(0);
  540.     if(!_GrMouseDrawn) return(0);
  541.     if(c == NULL) c = CURC;
  542.     if(!CHECK_CONTEXT(c)) return(0);
  543.     retval = queue->evq_drawmouse ? BLK_MOTION : 0;
  544.     queue->evq_drawmouse = FALSE;
  545.     queue->evq_moved = FALSE;
  546.     SORT2(x1,x2);
  547.     SORT2(y1,y2);
  548.     x1 += c->gc_xoffset; y1 += c->gc_yoffset;
  549.     x2 += c->gc_xoffset; y2 += c->gc_yoffset;
  550.     mx1 = _GrMouseCursor->cr_xwpos;
  551.     my1 = _GrMouseCursor->cr_ywpos;
  552.     mx2 = mx1 + _GrMouseCursor->cr_xwork - 1;
  553.     my2 = my1 + _GrMouseCursor->cr_ywork - 1;
  554.     if(ms_curmode != M_CUR_NORMAL) {
  555.         int cx2,cy2;
  556.         int cx1 = _GrMouseCursor->cr_xcord;
  557.         int cy1 = _GrMouseCursor->cr_ycord;
  558.         switch(ms_curmode) {
  559.           case M_CUR_RUBBER:
  560.           case M_CUR_LINE:
  561.         cx2 = ms_xanchor;
  562.         cy2 = ms_yanchor;
  563.         break;
  564.           case M_CUR_BOX:
  565.         cx2  = cx1 + ms_dx2;
  566.         cy2  = cy1 + ms_dy2;
  567.         cx1 += ms_dx1;
  568.         cy2 += ms_dy1;
  569.         break;
  570.           default:
  571.         return(retval);
  572.         }
  573.         SORT2(cx1,cx2);
  574.         SORT2(cy1,cy2);
  575.         if(cx1 < mx1) mx1 = cx1;
  576.         if(cy1 < my1) my1 = cy1;
  577.         if(cx2 > mx2) mx2 = cx2;
  578.         if(cy2 > my2) my2 = cy2;
  579.     }
  580.     if(mx1 > x1) x1 = mx1;
  581.     if(my1 > y1) y1 = my1;
  582.     if(mx2 < x2) x2 = mx2;
  583.     if(my2 < y2) y2 = my2;
  584.     if((x1 <= x2) && (y1 <= y2)) {
  585.         _GrMouseDrawn = FALSE;
  586.         retval |= BLK_DISPLAY;
  587.         erase_mouse();
  588.     }
  589.     if(_GrMouseCheck) {
  590.         _GrMouseCheck = FALSE;
  591.         retval |= BLK_CHECK;
  592.     }
  593.     return(retval);
  594. }
  595.  
  596. void MouseUnBlock(int flags)
  597. {
  598.     if(mouse_status < INITTED) return;
  599.     if(queue->evq_moved && (flags & BLK_MOTION)) move_mouse();
  600.     if(!_GrMouseDrawn && (flags & BLK_DISPLAY)) {
  601.         draw_mouse();
  602.         _GrMouseDrawn = TRUE;
  603.     }
  604.     _GrMouseCheck = ((CHECK_CONTEXT(CURC) && (flags & BLK_CHECK)) ?
  605.         TRUE :
  606.         FALSE
  607.     );
  608.     if(flags & BLK_MOTION) queue->evq_drawmouse = TRUE;
  609. }
  610.  
  611. void MouseEventEnable(int enable_kb,int enable_ms)
  612. {
  613.     if(mouse_status >= INITTED) {
  614.         queue->evq_enable =
  615.         (enable_kb ? EVENT_ENABLE(EVENT_KEYBD) : 0) |
  616.         (enable_ms ? EVENT_ENABLE(EVENT_MOUSE) : 0);
  617.     }
  618.     kb_enable = enable_kb;
  619.     ms_enable = enable_ms;
  620. }
  621.  
  622. void MouseGetEvent(int flags,MouseEvent *e)
  623. {
  624.     int erase = FALSE;
  625.  
  626.     if(!kb_enable) flags &= ~M_KEYPRESS;
  627.     if(!ms_enable) flags &= ~(M_MOTION | M_BUTTON_DOWN | M_BUTTON_UP);
  628.     if(!(flags & M_EVENT)) { e->flags = 0; return; }
  629.     if(!check_mouse()) {
  630.         e->flags = 0;
  631.         if((flags & M_KEYPRESS) && (!(flags & M_POLL) || kbhit())) {
  632.         e->flags  = M_KEYPRESS;
  633.         e->key      = getkey();
  634.         e->kbstat = getkbstat();
  635.         e->time      = clock();
  636.         }
  637.         return;
  638.     }
  639.     if(!_GrMouseDrawn && !(flags & M_NOPAINT)) {
  640.         draw_mouse();
  641.         queue->evq_drawmouse = TRUE;
  642.         erase = TRUE;
  643.     }
  644.     (*getevent)(flags,e);
  645.     if(erase) {
  646.         queue->evq_drawmouse = FALSE;
  647.         erase_mouse();
  648.     }
  649. }
  650.  
  651. int MousePendingEvent(void)
  652. {
  653.     if((mouse_status >= INITTED) && (queue->evq_cursize > 0))
  654.         return(TRUE);
  655.     return(FALSE);
  656. }
  657.  
  658.